//change to ASCII 

import java.io.*;
import java.util.*;

public class Main{
	static String version="v0.5 2013/09/04";//useless now

	static String tmpString="",allString="";
	static String[] tmpStringArray=new String[1];
	static String[] oldstring=new String[1];
	static String[] newstring=new String[1];
	static byte[] function=new byte[1];//function to modify string

	static String tablefile="table.txt",srcfile="a.txt",desfile="a_1.txt";
	static byte[] bytes=new byte[1];
				
	static int specialFunction=0;
	static int specialFunctionPara=0;
		//binary to hex
		static final int _F0_ADD_0_		=0x0001;	//add ","
		static final int _F0_ADD_1_		=0x0002;	//add ",0x"

		//hex to binary
		static final int _F1_ROV_0_		=0x0001;	//remove ","
		static final int _F1_ROV_1_		=0x0002;	//remove ",0x"

		static final int _F2_SHOW_COUNT_	=0x0001;
		static final int _F2_SHOW_ADDR_		=0x0002;
		static final int _F2_SHOW_LEN_		=0x0004;



	static byte warning=0;
	static byte specialFunctionParaCheck=0;
		static final int _BINARY2HEX_		=0x0001;
		static final int _HEX2BINARY_		=0x0002;
		static final int _INTELHEX2TABLE_	=0x0004;



	static File file;

	static FileOutputStream fileoutputstream;
	static BufferedInputStream bufferedinputstream;
	static ByteArrayOutputStream bytearrayoutputstream;
	static BufferedWriter bufferedwriter;
	static Extract extract=new Extract();
	static StringProcess sp=new StringProcess();


	public static void main(String[] args){
		try{

			for(int i=0;i<args.length;i++){
//System.out.println(i+":"+args[i]);
				warning=0;
				specialFunctionParaCheck=0;

				switch(args[i]){
					case "-s"://src file
						i++;
						if(i<args.length){

							if(args[i].charAt(0)=='-')
								warning=2;
							else
								srcfile=args[i];
						}
						else
							warning=1;

						if(warning>0)
							System.out.println("WARNING:-s need source file path");
						break;
					case "-d"://des file
						i++;
						if(i<args.length){
							if(args[i].charAt(0)=='-')
								warning=2;
							else
								desfile=args[i];
						}

						if(warning>0)
							System.out.println("WARNING:-d need destination file path");
						break;
					case "-t"://table file
						i++;
						if(i<args.length){
							if(args[i].charAt(0)=='-')
								warning=2;
							else
								tablefile=args[i];
						}

						if(warning>0)
							System.out.println("WARNING:-t need table file path");
						break;
					case "-v":
						System.out.println("-------------file convert version------");
						System.out.println("v0.5 2013/09/04");
						System.out.println("     1.modify -f \"Binary2Hex\" \"para\":for convert binary to hex");
						System.out.println("     2.modify -f \"Hex2Binary\" \"para\":for convert hex to binary");
						System.out.println("     3.add    -f \"InterHex2Table\" \"para\":for convert intel hex to table");

						System.out.println("     4.remove -f \"Binary2Hex1\"");
						System.out.println("     5.remove -f \"Binary2Hex2\"");
						System.out.println("     6.remove -f \"Hex2Binary1\"");
						System.out.println("     7.remove -f \"Hex2Binary2\"");

						System.out.println("v0.4 2013/09/03");
						System.out.println("     1.add -f \"Binary2Hex1\":for convert binary to hex add \",\"");
						System.out.println("     2.add -f \"Binary2Hex2\":for convert binary to hex add \",0x\"");
						System.out.println("     3.add -f \"Hex2Binary1\":for convert hex to binary remove \",\"");
						System.out.println("     4.add -f \"Hex2Binary2\":for convert hex to binary remove \",0x\"");
						System.out.println("v0.3 2013/09/01");
						System.out.println("     1.add -f \"Binary2Hex\" :for convert binary to hex");
						System.out.println("     2.add -f \"Hex2Binary\" :for convert hex to binary");
						System.out.println("v0.2 2013/07/23");
						System.out.println("     1.add \"\\CLR_A\" for clear char after  this pattern");
						System.out.println("     2.add \"\\CLR_B\" for clear char before this pattern");
						System.out.println("v0.1 2013/07/21");
						break;
					case "-h"://help
						System.out.println("-------------file convert help---------");
						System.out.println(" -s srcfile      :for source      file select");
						System.out.println(" -d desfile      :for destination file select");
						System.out.println(" -t tabfile      :for table       file select");
						System.out.println(" -v              :for show version");
						System.out.println(" -h              :for help");
						System.out.println(" -f \"Binary2Hex\" \"para\":for convert binary to hex");
						System.out.println("                  para[0]:add ','");
						System.out.println("                  para[1]:add ',0x'");
						System.out.println(" -f \"Hex2Binary\" \"para\":for convert hex to binary");
						System.out.println("                  para[0]:remove ','");
						System.out.println("                  para[1]:remove ',0x'");
						System.out.println(" -f \"IntelHex2Table\" \"para\":for convert hex to binary");
						System.out.println("                  para[0]:show count");
						System.out.println("                  para[1]:show addr");
						System.out.println("                  para[2]:show length");

						System.out.println();
						System.out.println("ex:-s a.txt -h -d a1.txt -t table.txt -f IntelHex2Table 01");
						break;
					case "-f"://specail fucntion
						i++;
						if(i<args.length){
							if(args[i].equalsIgnoreCase("Binary2Hex")){		
														//[0]:add ","
														//[1]:add ",0x"
								specialFunction|=_BINARY2HEX_;
								specialFunctionParaCheck=1;
							}
							else if(args[i].equalsIgnoreCase("Hex2Binary")){	
														//[0]:remove ","
														//[1]:remove ",0x"
								specialFunction|=_HEX2BINARY_;
								specialFunctionParaCheck=1;
							}
							else if(args[i].equalsIgnoreCase("IntelHex2Table")){
														//[0]:add byte in the last
														//[1]:add address in each line
								specialFunction|=_INTELHEX2TABLE_;
								specialFunctionParaCheck=1;
							}
						
							if(specialFunctionParaCheck>0){
								i++;
								if((i)<args.length){
									if(args[i].charAt(0)=='-'){
										warning=2;
									}
									else{
										specialFunctionPara=sp.byteToInt(sp.stringToByte(args[i]),0);
									}
//specialFunctionPara=0x07;
System.out.println("specialFunctionPara:"+specialFunctionPara);
								}
								else
									warning=2;
								
								if(warning>0){
									System.out.println("WARNING:-f need function select need para");
									System.out.println("     ex:-f IntelHex2Table 0");
								}
							}
						}
						else
							System.out.println("WARNING:-f need function select");

//specialFunction=0;
System.out.println("specialFunction:"+specialFunction);
						break;
					default:
						System.out.println("useless parameter:"+args[i]);
						break;
				}
			}
/*
System.out.println("src:"+srcfile);
System.out.println("des:"+desfile);
System.out.println("tab:"+tablefile);
*/

//			System.out.println("-------------file convert--------------");
			System.out.println("-----file convert--"+version+"-----");

			System.out.println("input\t="+srcfile);
			System.out.println("output\t="+desfile);
			System.out.println("table\t="+tablefile);
			System.out.println();
//==================================================================
//note:read table.txt
//==================================================================
			if(specialFunction==0){
				file=new File(tablefile);

				bufferedinputstream=new BufferedInputStream(new FileInputStream(file));
				bytearrayoutputstream=new ByteArrayOutputStream();

				while(bufferedinputstream.read(bytes)!=-1){
					bytearrayoutputstream.write(bytes);
				}			
				bytearrayoutputstream.close();
				bufferedinputstream.close();



				allString=bytearrayoutputstream.toString();

//==================================================================
//note:get replace string pattern
//==================================================================
//System.out.println("start-------");


//System.out.println("stop-------");
//System.out.println(allString);


				extract=new Extract(allString);

				oldstring=new String[extract.getReplaceCount()];
				newstring=new String[extract.getReplaceCount()];
				function=new byte[extract.getReplaceCount()];

				oldstring=extract.getOldString();
				newstring=extract.getNewString();
				function=extract.getFunction();
//for(int i=0;i<oldstring.length;i++){
//	System.out.println("old:"+oldstring[i]);
//	System.out.println("new:"+newstring[i]);
//}
			}
//==================================================================
//note:read source file
//==================================================================
			file=new File(srcfile);

			bufferedinputstream=new BufferedInputStream(new FileInputStream(file));
			bytearrayoutputstream=new ByteArrayOutputStream();

			
			long filesize=bufferedinputstream.available();
			while(bufferedinputstream.read(bytes)!=-1){
				bytearrayoutputstream.write(bytes);
			}			
			bytearrayoutputstream.close();
			bufferedinputstream.close();
	

//==================================================================
//note:start convert
//==================================================================
			if(specialFunction==0){
				allString=bytearrayoutputstream.toString();
/*
System.out.println("src file------------");

System.out.println(allString);
*/
				System.out.println("input file size\t\t="+filesize+" bytes");
				System.out.println("replace item number\t="+extract.getReplaceCount());
				System.out.println("0-----------start convert----------100%");
				int percentage=0;

				for(int i=0;i<extract.getReplaceCount();i++){
					if(i>0){
						if(((i*40/extract.getReplaceCount()))!=percentage){
							System.out.print("|");
							percentage=(i*40/extract.getReplaceCount());
						}
					}

					if(function[i]>0){

						if((function[i]&0x01)==0x01){//\CLR_A
//System.out.println("function"+i+":"+function[i]);
//System.out.println("oldstring["+i+"]="+oldstring[i]);
//System.out.println(allString.indexOf(oldstring[i]));
							while(allString.indexOf(oldstring[i])!=-1){
							
								if((allString.indexOf(oldstring[i])+oldstring[i].length())==allString.length() || allString.indexOf("\r\n",allString.indexOf(oldstring[i])+1)==-1){//last string
									allString=allString.substring(0,allString.indexOf(oldstring[i]));
								}
								else{
									allString=allString.substring(0,allString.indexOf(oldstring[i]))+allString.substring(allString.indexOf("\r\n",allString.indexOf(oldstring[i])+1),allString.length());
								}
							}
						}


						if((function[i]&0x02)==0x02){//\CLR_B
							while(allString.indexOf(oldstring[i])!=-1){
//							if(allString.indexOf(oldstring[i])!=-1){
/*
System.out.println();
System.out.println("\\CLR_B:"+oldstring[i]);
System.out.println(allString.indexOf(oldstring[i]));
System.out.println(allString.lastIndexOf("\r\n",allString.indexOf(oldstring[i])));
//allString=allString.substring(0,allString.lastIndexOf("\r\n",allString.indexOf(oldstring[i])));
//for(int k=0;k<allString.length();k++)
//System.out.println((byte)allString.charAt(k));
*/
								if(allString.indexOf(oldstring[i])==0){
									allString=allString.substring(allString.indexOf(oldstring[i])+oldstring[i].length(),allString.length());
								}
								else{
									allString=allString.substring(0,allString.lastIndexOf("\r\n",allString.indexOf(oldstring[i]))+2)+allString.substring(allString.indexOf(oldstring[i])+oldstring[i].length(),allString.length());
								}
							}
						}
					}
					else{
						allString=allString.replace(oldstring[i],newstring[i]);
					}
				}
				System.out.println();
/*
System.out.println("des file------------");

System.out.println(allString);
*/
			}
//==================================================================
//note:save output file
//==================================================================
			file=new File(desfile);	

			if(specialFunction==0){
				bytes=allString.getBytes();

				bufferedwriter=new BufferedWriter(new FileWriter(file));
				for(int i=0;i<bytes.length;i++){
					bufferedwriter.write(bytes[i]);
				}
				bufferedwriter.flush();
				bufferedwriter.close();
			}

			else if((specialFunction&(_INTELHEX2TABLE_))>0){
				System.out.println("-------------IntelHex2Table------------");

				bytes=IntelHex2Table(specialFunctionPara).getBytes();

				bufferedwriter=new BufferedWriter(new FileWriter(file));

				for(int i=0;i<bytes.length;i++){
					bufferedwriter.write(bytes[i]);
				}
				bufferedwriter.flush();
				bufferedwriter.close();

			}
			else if((specialFunction&(_BINARY2HEX_))>0){
				System.out.println("--------------Binary2Hex---------------");


				
				bytes=Binary2Hex(specialFunctionPara).getBytes();


//for(int i=0;i<bytes.length;i++){
//System.out.println("bytes["+i+"]="+sp.byteToString(bytes[i]));
//}
				fileoutputstream=new FileOutputStream(file);
				for(int i=0;i<bytes.length;i++){
					fileoutputstream.write(bytes[i]);
				}		
				fileoutputstream.close();
			}
			else if((specialFunction&(_HEX2BINARY_))>0){
				System.out.println("--------------Hex2Binary---------------");

				bytes=sp.stringToByte(Hex2Binary(specialFunctionPara));

//for(int i=0;i<bytes.length;i++){
//System.out.println("bytes["+i+"]="+sp.byteToString(bytes[i]));
//}
				fileoutputstream=new FileOutputStream(file);
				for(int i=0;i<bytes.length;i++){
					fileoutputstream.write(bytes[i]);
				}		
				fileoutputstream.close();

			}



//System.out.println("finish------------");
		}
		catch(ArrayIndexOutOfBoundsException e){
			e.printStackTrace();
		}
		catch(IOException e){
			e.printStackTrace();
		}
	}


//==================================================================
//note:convert intel hex to table
//==================================================================
	static String IntelHex2Table(int para){
		int tmpInt=0,tmpIndex,tmpIndexFirst,tmpCount,tmpAddr,tmpTotalCount;
				
		allString=bytearrayoutputstream.toString();
			
		tmpString=allString;
		while(tmpString.indexOf(":")!=-1){
			tmpString=tmpString.replaceFirst(":","");					
			tmpInt++;
		}
		tmpTotalCount=0;

		while((tmpIndexFirst=allString.indexOf(":"))!=-1){

			tmpIndex=tmpIndexFirst;
			allString=allString.replaceFirst(":","");
			bytes=sp.stringToByte(allString.substring(tmpIndex,tmpIndex+2));
			tmpCount=sp.byteToInt(bytes[0]);
			tmpIndex+=2;

			bytes=sp.stringToByte(allString.substring(tmpIndex,tmpIndex+4));
			tmpAddr=sp.byteToInt(bytes,0);

//System.out.println("allString_3------------------");
//System.out.println(allString);
//System.out.println("tmpIndexFirst="+tmpIndexFirst);
//System.out.println("tmpCount="+tmpCount);
//System.out.println();
			tmpIndex+=(4+2);
//			allString=allString.replaceFirst(allString.substring(tmpIndexFirst,tmpIndex),"");//remove header
			allString=allString.substring(0,tmpIndexFirst)+allString.substring(tmpIndex,allString.length());//remove header
//System.out.println("allString_4------------------");
//System.out.println(allString);
//System.out.println("tmpIndexFirst="+tmpIndexFirst);
//System.out.println("tmpCount="+tmpCount);
//System.out.println();
//			allString=allString.replaceFirst(allString.substring(tmpIndexFirst+tmpCount*2,tmpIndexFirst+tmpCount*2+2),"");//remove checksum
			allString=allString.substring(0,tmpIndexFirst+tmpCount*2)+allString.substring(tmpIndexFirst+tmpCount*2+2,allString.length());//remove checksum
//System.out.println("allString_0------------------");
//System.out.println(allString);
//System.out.println("tmpIndexFirst="+tmpIndexFirst);
//System.out.println("tmpCount="+tmpCount);
//System.out.println();
			if((tmpIndex=allString.indexOf("\r\n",tmpIndexFirst))!=-1){
			}
			else{
				tmpIndex=allString.length();
			}
			tmpString=allString.substring(0,tmpIndexFirst);						
	
			for(int i=0;i<(tmpIndex-tmpIndexFirst)/2;i++){
				tmpString+=",0x";
				tmpString+=allString.substring(tmpIndexFirst+i*2,tmpIndexFirst+i*2+2);
				tmpTotalCount++;
			}
//System.out.println("allString_1------------------");
//System.out.println(allString);
//System.out.println();

			if((para&_F2_SHOW_ADDR_)==_F2_SHOW_ADDR_){
//System.out.println("tmpAddr="+tmpAddr);
				tmpString+=("\t//addr= "+tmpAddr+" ");
				if((para&_F2_SHOW_LEN_)==_F2_SHOW_LEN_){
					tmpString+=("\tlen= "+tmpCount+" ");
				}
			}
			else if((para&_F2_SHOW_LEN_)==_F2_SHOW_LEN_){
				tmpString+=("\t//len= "+tmpCount+" ");
			}

			tmpString+=allString.substring(tmpIndex,allString.length());	
			allString=tmpString;
//System.out.println("allString_2------------------");
//System.out.println(allString);
//System.out.println();
//System.out.println();
//System.out.println();
		}

		if((para&_F2_SHOW_COUNT_)==_F2_SHOW_COUNT_){
			allString+="\r\n\r\n";
			allString+="//total byte= "+tmpTotalCount;
		}
		
		return allString;
	}

//==================================================================
//note:convert binary to hex
//==================================================================
	static String Binary2Hex(int para){

		bytes=bytearrayoutputstream.toByteArray();

		if((para&(_F0_ADD_0_))==_F0_ADD_0_){		//add "," in front of char
			allString=sp.byteToStringAdd(bytes,",");
		}
		else if((para&(_F0_ADD_1_))==_F0_ADD_1_){	//add ",0x" in front of char
			allString=sp.byteToStringAdd(bytes,",0x");
		}
		else{
			allString=sp.byteToString(bytes);
		}

//System.out.println("allString="+allString);
		return allString;
	}


//==================================================================
//note:convert intel hex to table
//==================================================================
	static String Hex2Binary(int para){
		allString=bytearrayoutputstream.toString();

		if(sp.isStringValid(allString)){//remove useles 
			tmpString="\r\n";
			while(allString.indexOf(tmpString)!=-1){
				allString=allString.replaceFirst(tmpString,"");
			}
			tmpString="\n";
			while(allString.indexOf(tmpString)!=-1){
				allString=allString.replaceFirst(tmpString,"");
			}
			tmpString="\r";
			while(allString.indexOf(tmpString)!=-1){
				allString=allString.replaceFirst(tmpString,"");
			}
		}

		if((para&_F1_ROV_0_)==_F1_ROV_0_){		//remove ","
			if(sp.isStringValid(allString)){
				tmpString=",";
				while(allString.indexOf(tmpString)!=-1){
					allString=allString.replaceFirst(tmpString,"");
				}
			}
		}
		else if((para&_F1_ROV_1_)==_F1_ROV_1_){	//remove ",0x"
			if(sp.isStringValid(allString)){
				tmpString=",";
				while(allString.indexOf(tmpString)!=-1){
					allString=allString.replaceFirst(tmpString,"");
				}
				tmpString="0x";
				while(allString.indexOf(tmpString)!=-1){
					allString=allString.replaceFirst(tmpString,"");
				}
				tmpString="0X";
				while(allString.indexOf(tmpString)!=-1){
					allString=allString.replaceFirst(tmpString,"");
				}
			}
		}
		return allString;
	}



}




